package com.example.slidingmenu;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

/**
 * Created by Administrator on 2016/10/8 0008.
 */

public class SlidingMenu extends ViewGroup {
    private final int screen_left=0;
    private final int screen_main=1;
    private int current_screen=1;
    private int downx,movex;
    private Scroller mScroller;
    private int slopx;
    public SlidingMenu(Context context) {
        super(context);
        initData();
    }

    public SlidingMenu(Context context, AttributeSet attrs) {
        super(context, attrs);
        initData();
    }

    /**
     * 相关初始化
     */
    private void initData() {
        mScroller=new Scroller(getContext());
        //安卓配置类
        slopx=ViewConfiguration.get(getContext()).getScaledTouchSlop();
    }

    public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 测量
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        View menuview=getChildAt(0);
        menuview.measure(menuview.getLayoutParams().width,heightMeasureSpec);
        View mainview=getChildAt(1);
        mainview.measure(widthMeasureSpec,heightMeasureSpec);
    }

    /**
     * 布局
     * @param changed
     * @param l
     * @param t
     * @param r
     * @param b
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        View menuview=getChildAt(0);
        menuview.layout(-menuview.getMeasuredWidth(),t,0,b);
        View mainview=getChildAt(1);
        mainview.layout(l,t,r,b);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downx= (int) event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                movex= (int) event.getX();
                int offsetx=downx-movex;
                //简而言之，getScrollX() 就是当前view的左上角相对于母视图的左上角的X轴偏移量。
                int viewx=getScrollX();
                if (viewx < -getChildAt(0).getMeasuredWidth()) {
//                    超出左边界
                    scrollTo(-getChildAt(0).getMeasuredWidth(),0);
                }else if(viewx>0){
//                    超出右边界
                scrollTo(0,0);
            }else{
                scrollBy(offsetx,0);
            }
                downx=movex;
                break;
            case MotionEvent.ACTION_UP:
                int x=getScrollX();
                if (x<-getChildAt(0).getMeasuredWidth()/2) {
                    current_screen=screen_left;
                } else {
                    current_screen=screen_main;
                }
                switchScreen();
                break;
        }
        return true;
    }

    /**
     * 根据状态切换屏幕
     */
    private void switchScreen() {
        int startX=getScrollX();
        int dx;
        //增量值=目的地值-开始值。
        if (current_screen == screen_left) {
            dx=-getChildAt(0).getMeasuredWidth()-startX;
//            scrollTo(-getChildAt(0).getMeasuredWidth(),0);这种方式是瞬间切换
        }else{
//            scrollTo(0,0);
            dx=0-startX;
        }
        mScroller.startScroll(startX,0,dx,0,Math.abs(dx)*5);//只负责模拟数据，不负责切换屏幕
        invalidate();//viewgroup中没有ondraw方法，会调用drawchild方法》》view.draw()》》view.computeScroll
    }

    @Override
    public void computeScroll() {
        int currentx=mScroller.getCurrX();//获取上面startscroll模拟的数据
        if (mScroller.computeScrollOffset()) {//当前正在模拟，此时不需要别的判断，因为invalidate不调用，自然就停止了
            scrollTo(currentx,0);
            invalidate();//继续调用computeScroll
        }
    }

    public boolean isShow() {
        return current_screen==screen_left;
    }

    /**
     * 显示菜单
     */
    public void showLeft() {
        current_screen=screen_left;
        switchScreen();
    }

    /**
     * 隐藏菜单
     */
    public void hindLeft() {
        current_screen=screen_main;
        switchScreen();
    }

    /**
     * 事件分发机制
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //只在横着滑动的时候拦截
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downx= (int) ev.getX();//切记是ev.getX()，而不是直接getX().

            break;
            case MotionEvent.ACTION_MOVE:
                movex= (int)ev.getX();
                int offset=downx-movex;
                //如果不用事件分发，那么在侧拉里面不能进行左滑动啥的，此时在侧拉栏里面如果水平移动距离是
                //大于10就拦截事件，不大于10不拦截，这样可以有效防止侧拉栏不能上下滑动
                if (Math.abs(offset)>slopx) {//之所以用slopx是因为如果用固定值10，在大手机上面过于灵敏
                    return true;
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }
}
